package com.ecoolex.discount.sales.core.utils;

import com.ecoolex.discount.sales.pojo.CtripYWResponse;
import com.ecoolex.framework.common.util.StringUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.DigestUtils;

import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Slf4j
public class SignUtils {

    public static CtripYWResponse sign(CtripYWResponse ctripYWResponse, String secret, ObjectMapper objectMapper) {
        Map<String, String> params = new HashMap<>();
        params.put("errno", ctripYWResponse.getErrno());
        params.put("errmsg", ctripYWResponse.getErrmsg());

        if(Objects.nonNull(ctripYWResponse.getData())){
            try {
                params.put("data", objectMapper.writeValueAsString(ctripYWResponse.getData()));
                //log.info(objectMapper.writeValueAsString(params));
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
        }
        String str = sortAndConcactString(params);
        String encodeString = Base64.getEncoder().encodeToString(str.getBytes(StandardCharsets.UTF_8));
        String sign = DigestUtils.md5DigestAsHex((encodeString + "#" + secret).getBytes(StandardCharsets.UTF_8));
        ctripYWResponse.setSign(sign);
        return ctripYWResponse;
    }

    public static String sign(Map<String,String> params,String secret) {
        String str = sortAndConcactString(params);
        String encodeString = Base64.getEncoder().encodeToString(str.getBytes(StandardCharsets.UTF_8));
        String sign = DigestUtils.md5DigestAsHex((encodeString + "#" + secret).getBytes(StandardCharsets.UTF_8));
        return sign;
    }

    public static String sortAndConcactString(Map<String, String> params) {
        List<String> keys = params.keySet().stream().filter(key -> !"sign".equals(key)).collect(Collectors.toList());
        Collections.sort(keys);
        Collections.reverse(keys);
        StringBuilder sb = new StringBuilder();
        Iterator<String> iterator = keys.iterator();
        while (iterator.hasNext()) {
            String key = iterator.next();
            if (!StringUtil.isEmpty(params.get(key))) {
                sb.append(key).append("=").append(params.get(key));
                if (iterator.hasNext()) {
                    sb.append("|");
                }
            }
        }
        return sb.toString();
    }

    public static Boolean verity(Map<String, String> params,String secret){
        String sign = params.get("sign");
        String str = sortAndConcactString(params);
        String encodeString = Base64.getEncoder().encodeToString(str.getBytes(StandardCharsets.UTF_8));
        String encrypted = DigestUtils.md5DigestAsHex((encodeString + "#" + secret).getBytes(StandardCharsets.UTF_8));
        return sign.equals(encrypted);
    }
}
